﻿#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <list>
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_CommHdr.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_Types.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_AvCoder/NetEngine_AVCollect/AVCollect_Define.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_AvCoder/NetEngine_VideoCoder/VideoCoder_Define.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_AvCoder/NetEngine_VideoCoder/VideoCoder_Error.h"

//g++ -std=gnu++11 -Wall -g Test_AVVideo.cpp -o Test_AVVideo -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_BaseLib -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_AvCoder -lNetEngine_BaseLib -lNetEngine_VideoCoder -Wl,-rpath=./:../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_BaseLib:../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_AvCoder,--disable-new-dtags

XNETHANDLE xhDeVideo;
XNETHANDLE xhEnVideo;
XNETHANDLE xhFilterVideo;
FILE *pSt_YUVFile;
FILE *pSt_264File;

void __stdcall VideoCodec_Stream_Callback(XNETHANDLE xhVideo, uint8_t *pszYBuffer, uint8_t *pszUBuffer, uint8_t *pszVBuffer, int nYLen, int nULen, int nVLen, AVCODEC_VIDEO_INFO *pSt_VideoInfo, LPVOID lParam)
{
    printf("%llu: %d nWidth:%d nHeight:%d\n", xhVideo, pSt_VideoInfo->en_FrameType, pSt_VideoInfo->nWidth, pSt_VideoInfo->nHeight);
    //fwrite(pszYBuffer, 1, nYLen, pSt_YUVFile);
    //fwrite(pszUBuffer, 1, nULen, pSt_YUVFile);
    //fwrite(pszVBuffer, 1, nVLen, pSt_YUVFile);
    int nLen = 1920 * 1080 * 3;
    int nFilterLen = 1920 * 1080 * 3;
    uint8_t *ptszEnBuffer = (uint8_t *)malloc(nLen);
    uint8_t *ptszFilterBuffer = (uint8_t *)malloc(nFilterLen);

    memset(ptszEnBuffer, '\0', nLen);
    memset(ptszFilterBuffer, '\0', nFilterLen);

    nLen = 0;

    if (VideoCodec_Help_FilterCvt(xhFilterVideo, pszYBuffer, pszUBuffer, pszVBuffer, nYLen, nULen, nVLen, ptszFilterBuffer, &nFilterLen))
    {
        int nRet = fwrite(ptszFilterBuffer, 1, nFilterLen, pSt_YUVFile);
        printf("%d == %d\n", nFilterLen,nRet);

        VideoCodec_Stream_EnCodec(xhEnVideo, ptszFilterBuffer, NULL, NULL, nFilterLen, 0, 0, ptszEnBuffer, &nLen);
        if (nLen > 0)
        {
            fwrite(ptszEnBuffer, 1, nLen, pSt_264File);
        }
    }
    free(ptszEnBuffer);
    free(ptszFilterBuffer);
}
int Test_CodecFilter()
{
    FILE *pSt_File = _tfopen("1080P.264", "rb");
    pSt_264File = _tfopen("en.h264", "wb");
    pSt_YUVFile = _tfopen("ds.yuv", "wb");

    if (!VideoCodec_Stream_EnInit(&xhEnVideo, 1920, 1080, ENUM_ENTENGINE_AVCODEC_VEDIO_TYPE_H264))
    {
        printf("VideoCodec_Stream_EnInit\n");
        return -1;
    }
    if (!VideoCodec_Stream_DeInit(&xhDeVideo, ENUM_ENTENGINE_AVCODEC_VEDIO_TYPE_H264, VideoCodec_Stream_Callback))
    {
        printf("VideoCodec_Stream_DeInit\n");
        return -1;
    }
    const char *filter_descr = "drawtext=fontfile=Arial.ttf:fontcolor=green:fontsize=30:x=100:y=10:text='www.xyry.org'";
    VideoCodec_Help_FilterInit(&xhFilterVideo, filter_descr, 1920, 1080);
    while (1)
    {
        TCHAR tszBuffer[10240];
        memset(tszBuffer, '\0', sizeof(tszBuffer));
        int nRet = fread(tszBuffer, 1, 10240, pSt_File);
        if (nRet <= 0)
        {
            break;
        }
        if (!VideoCodec_Stream_DeCodec(xhDeVideo, (uint8_t *)tszBuffer, nRet))
        {
            printf("VideoCodec_Stream_DeCodec\n");
        }
    }
    VideoCodec_Stream_DeCodec(xhDeVideo, NULL, 0);
    VideoCodec_Stream_Destroy(xhDeVideo);

    VideoCodec_Stream_Destroy(xhDeVideo);
    VideoCodec_Stream_Destroy(xhEnVideo);
    return 0;
}
int Test_Encodec()
{
    XNETHANDLE xhVideo;
    int nSize = 1920 * 1080 * 3 / 2;
    TCHAR *tszDeBuffer = new TCHAR[nSize];
    TCHAR tszEnBuffer[102400];

    if (!VideoCodec_Stream_EnInit(&xhVideo, 1920, 1080, ENUM_ENTENGINE_AVCODEC_VEDIO_TYPE_H264))
    {
        printf("VideoCodec_Stream_EnInit\n");
        return -1;
    }
    FILE *pSt_File = _tfopen("E:\\NetEngine_Windows\\NetEngine_Apps\\Debug\\ds.h264", "wb");
    FILE *pSt_YUV = _tfopen("D:\\360Downloads\\ffmpeg-4.0.2-win32-shared\\bin\\out.yuv", "rb");

    while (1)
    {
        memset(tszEnBuffer, '\0', sizeof(tszEnBuffer));
        memset(tszDeBuffer, '\0', nSize);

        int nRet = fread(tszDeBuffer, 1, nSize, pSt_YUV);
        if (nRet <= 0)
        {
            break;
        }
        int nLen = 0;
        VideoCodec_Stream_EnCodec(xhVideo, (uint8_t *)tszDeBuffer, NULL, NULL, nRet, 0, 0, (uint8_t *)tszEnBuffer, &nLen);
        if (nLen > 0)
        {
            fwrite(tszEnBuffer, 1, nLen, pSt_File);
        }
    }
    fclose(pSt_File);
    fclose(pSt_YUV);
    VideoCodec_Stream_Destroy(xhVideo);
    return 0;
}
int main()
{
    list<AVCODEC_VIDEO_HWCODEC> stl_ListHWCodec;
    VideoCodec_Help_GetHWCodec(&stl_ListHWCodec);
    list<AVCODEC_VIDEO_HWCODEC>::const_iterator stl_ListIterator = stl_ListHWCodec.begin();
    for (;stl_ListIterator != stl_ListHWCodec.end();stl_ListIterator++)
    {
        printf("%d = %s\n", stl_ListIterator->enHWDevice, stl_ListIterator->tszHWName);
    }
    Test_CodecFilter();
    return 0;
}
